package gao.xiaolei.service;

import com.google.gson.*;
import gao.xiaolei.dao.*;
import gao.xiaolei.entity.*;
import org.springframework.stereotype.Service;
import gao.xiaolei.util.GsonUtil;
import gao.xiaolei.util.RedisUtil;
import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service("RoleService")
public class RoleService {

    @Resource(name="UrlRoleDao")
    private UrlRoleDao urlRoleDao;

    @Resource(name="UserRoleDao")
    private UserRoleDao userRoleDao;

    @Resource(name="RoleDao")
    private RoleDao roleDao;

    @Resource(name="UrlDao")
    private UrlDao urlDao;

    @Resource(name="UserDao")
    private UserDao userDao;

    @Resource(name = "AuthVersionDao")
    private AuthVersionDao authVersionDao;

    @Resource(name = "GsonUtil")
    private GsonUtil gsonUtil;

    @Resource(name = "RedisUtil")
    private RedisUtil redis;

    @Transactional
    //修改或者添加角色的权限
    public void updateRoleAuth(String role_id, String newUrlJson) {
        JsonArray newUrls = new JsonParser().parse(newUrlJson).getAsJsonArray();
        for (JsonElement newUrl : newUrls) {
            urlRoleDao.save(new UrlRole(newUrl.getAsString(), role_id));
        }
        List<String> userIds=userRoleDao.getUserByRoleId(role_id);
        List<User> users=userDao.findAllById(userIds);
        for(int i=0,length=users.size();i<length;i++){//更改了角色说明权限要发生改变，所以要将权限版本号变更
            AuthVersion av=authVersionDao.findById(users.get(i).getId()).orElse(new AuthVersion(users.get(i).getId(),0));
            av.setVersion(av.getVersion()+1);
            authVersionDao.save(av);
            redis.set(users.get(i).getId(),av.getVersion(),redis.EXPIRETIME);
        }
    }

    @Transactional
    public Integer addRole(String roleJson){
        JsonObject roleObject = new JsonParser().parse(roleJson)
                .getAsJsonObject();
        String id = roleObject.get("id").getAsString();
        String name = roleObject.get("name").getAsString();
        String chineseName = roleObject.get("chineseName").getAsString();
        if (roleDao.findByNameOrChineseName(name,chineseName) != null)
            return 0;
        JsonArray baseRoles = roleObject.get("baseRoles").getAsJsonArray();
        Set<String> url1 = new HashSet<String>();// 储存要从其他角色继承的权限
        List<String> url2 = null;// 储存某个角色的权限
        roleDao.save(new Role(id,name, chineseName));
        for (JsonElement baseRole : baseRoles) {
            url2 = urlRoleDao.queryUrlByRoleId(baseRole.getAsString());
            if (url2 != null) {
                for (int i = 0, length = url2.size(); i < length; i++) {
                    url1.add(url2.get(i));
                }
            }
        }
        for (String urlId : url1) {// 遍历Set,将角色继承的权限加入到urlRole表
            urlRoleDao.save(new UrlRole(urlId, id));
        }
        return 1;
    }

    @Transactional
    public void deleteRole(String roleIdJson) {
        JsonArray roleIds = new JsonParser().parse(roleIdJson).getAsJsonArray();
        for (JsonElement roleId : roleIds) {
            String id = roleId.getAsString();
            List<String> userIds=userRoleDao.getUserByRoleId(id);
            List<User> users=userDao.findAllById(userIds);
            for(int i=0,length=users.size();i<length;i++){//更改了角色说明权限要发生改变，所以要将权限版本号变更
                AuthVersion av=authVersionDao.findById(users.get(i).getId()).orElse(new AuthVersion(users.get(i).getId(),0));
                av.setVersion(av.getVersion()+1);
                authVersionDao.save(av);
                redis.set(users.get(i).getId(),av.getVersion(),redis.EXPIRETIME);
            }
            urlRoleDao.deleteByRoleId(id);
            roleDao.deleteById(id);
        }
    }

    public List<Url> getRoleAuth(String role_id) {
        return urlDao.findAllById(urlRoleDao.queryUrlByRoleId(role_id));
    }

    @Transactional
    public List<Url> getCanAddAuth(String roleId) {
        List<String> hasUrls = urlRoleDao.queryUrlByRoleId(roleId);
        List<Url> allUrl = urlDao.findAll();
        for (int i = 0, length = hasUrls.size(); i < length; i++) {
            for (int j = 0, length2 = allUrl.size(); j < length2; j++) {
                if (allUrl.get(j).getId().equals(hasUrls.get(i))) {
                    allUrl.remove(j);
                    break;
                }
            }
        }
        return allUrl;
    }

    @Transactional
    public void deleteAuth(String roleId, String delUrlJson) {
        JsonArray urlIds = new JsonParser().parse(delUrlJson).getAsJsonArray();
        for (JsonElement urlId : urlIds) {
            urlRoleDao.delete(new UrlRole(urlId.getAsString(), roleId));
        }
        List<String> userIds=userRoleDao.getUserByRoleId(roleId);
        List<User> users=userDao.findAllById(userIds);
        for(int i=0,length=users.size();i<length;i++){//更改了角色说明权限要发生改变，所以要将权限版本号变更
            AuthVersion av=authVersionDao.findById(users.get(i).getId()).orElse(new AuthVersion(users.get(i).getId(),0));
            av.setVersion(av.getVersion()+1);
            authVersionDao.save(av);
            redis.set(users.get(i).getId(),av.getVersion(),redis.EXPIRETIME);
        }
    }

    public List<Role> getAll() {
        return roleDao.findAll();
    }
}
